package cl.zeke.pizzastore.finders;

import cl.zeke.pizzastore.dto.FiltroUsuariosDto;
import cl.zeke.pizzastore.negocio.entities.Usuario;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public class UsuarioFinder {
    
    private static Logger log = LoggerFactory.getLogger(UsuarioFinder.class);
    
    @PersistenceContext
    private EntityManager em;
    

    public Usuario traerPorEmail(String email) {
        List<Usuario> list = em.createNamedQuery("Usuario.findByEmail", Usuario.class)
                .setParameter("email", email)
                .getResultList();
        if(list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    public Usuario traerConPerfilesPorEmailYPassword(String email, String password) {
        
        List<Usuario> list = em.createNamedQuery("Usuario.traerConPerfilesPorEmailYPassword")
                .setParameter("email", email)
                .setParameter("password", password)
                .getResultList();
        
        if(list.isEmpty()) {
            return null;
        }
        
        return list.get(0);
    }

    public List<Usuario> traerTodos() {
        return em.createNamedQuery("Usuario.findAll", Usuario.class)
                .getResultList();
    }

    public List<Usuario> buscar(FiltroUsuariosDto filtro) {
        
        String jpql = 
                "SELECT DISTINCT u FROM Usuario u "
                + "LEFT JOIN FETCH u.cliente c "
                + "INNER JOIN FETCH u.perfilList p "
                + "WHERE 1=1 ";
        
        Map<String,Object> propiedades = new HashMap<>();
        
        if(filtro.getEstado() != null) {
            jpql += "AND u.activo = :estado ";
            propiedades.put("estado", filtro.getEstado());
        }
        if(filtro.getEmail() != null) {
            jpql += "AND u.email = :email ";
            propiedades.put("email", filtro.getEmail());
        }
        if(filtro.getFechaNacDesde()!=null) {
            jpql += "AND c.fechaNacimiento >= :fechadesde ";
            propiedades.put("fechadesde", filtro.getFechaNacDesde());
        }
        if(filtro.getFechaNacHasta() != null) {
            jpql += "AND c.fechaNacimiento <= :fechahasta ";
            propiedades.put("fechahasta", filtro.getFechaNacHasta());
        }
        if(filtro.getPerfil()!= null) {
            jpql += "AND :perfil in elements(u.perfilList) ";
            propiedades.put("perfil", filtro.getPerfil());
        }
        if(filtro.getRut()!= null) {
            jpql += "AND c.run = :rut ";
            propiedades.put("rut", filtro.getRut());
        }
        
        Query query = em.createQuery(jpql);
        for(String nombrePropiedad: propiedades.keySet()) {
            query.setParameter(nombrePropiedad, propiedades.get(nombrePropiedad));
        }
        return query.getResultList();
        
    }
    
}
